Controllers and callbacks topic
Controllers & Callbacks
This is part of the kalender documentation.
Controllers drive the calendar from your code. Callbacks report back what the user did. Together they are how the calendar connects to the rest of your app.
Controllers
EventsController
EventsController manages and exposes events to the calendar. Typically one instance per app. Use DefaultEventsController unless you need a custom storage layer.
Its methods are addEvent, addEvents, removeEvent, removeEvents, removeWhere, removeById, updateEvent, replaceEvents, byId, clearEvents and eventsInRange.
eventsInRange takes a FloatingDateTimeRange, not a KalenderDateTimeRange.
Convert with FloatingDateTimeRange.fromDateTimeRange(range).
KalenderController
KalenderController drives the KalenderView widgets built on it. It holds the viewConfiguration and location. Setting either switches the view, see Switching between views and Location.
State notifiers:
| Notifier | Type | Description |
|---|---|---|
visibleDateTimeRange |
ValueListenable<KalenderDateTimeRange> |
The currently visible date range |
floatingVisibleRange |
ValueListenable<FloatingDateTimeRange> |
The same range without a timezone |
visibleTimeOfDay |
ValueListenable<KalenderTime?> |
Time aligned with the top of the viewport (multi-day views, null otherwise) |
visibleEvents |
ValueListenable<Set<KalenderEvent>> |
Events on the page on screen |
selectedEvent |
ValueNotifier<KalenderEvent?> |
The focused event (shows drop target / resize handles) |
selectedRange |
ValueNotifier<FloatingDateTimeRange?> |
The selected days, ending at midnight after the last one |
openDayOverlay |
ValueNotifier<FloatingDateTime?> |
The day whose overlay is open (month view and multi-day header, null otherwise) |
Navigation methods:
jumpToPage(page)/jumpToDate(date)animateToNextPage()/animateToPreviousPage()animateToDate(date)/animateToDateTime(dateTime)animateToEvent(event)
Selection methods: selectEvent(event) focuses an event from code, which is
what draws its drop target and resize handles. deselectEvent() clears it. Both
drive the selectedEvent notifier above. selectDate(date) and
selectRange(range) select whole days, deselectRange() clears them and
isDateSelected(date) tests one. They drive selectedRange. Pass
navigate: true to move the view to a selection that is off screen.
Day overlay: showDayOverlay(date) opens the overlay listing a day's events
in the month view and the multi-day header, and hideDayOverlay() closes it.
Both drive openDayOverlay. A day off screen opens nothing unless
navigate: true is passed.
Disposing
Both controllers hold listeners, so dispose them with the widget that owns them:
kalenderController.dispose();
eventsController.dispose();
An EventsController shared across screens belongs to whatever owns it for the
life of the app, and is disposed there rather than in a single screen.
Building the surrounding UI
The calendar draws no toolbar of its own. Switching views, moving between pages
and showing the current month are all built in your app, using the navigation
methods above and the controller's viewConfiguration.
class CalendarScreen extends StatefulWidget {
const CalendarScreen({super.key});
@override
State<CalendarScreen> createState() => _CalendarScreenState();
}
class _CalendarScreenState extends State<CalendarScreen> {
final viewConfigurations = <ViewConfiguration>[
MultiDayViewConfiguration.week(),
MonthViewConfiguration.singleMonth(),
];
late final kalenderController = KalenderController(viewConfiguration: viewConfigurations.first);
@override
void dispose() {
kalenderController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
children: [
ValueListenableBuilder(
valueListenable: kalenderController.floatingVisibleRange,
builder: (context, range, child) {
final month = range.dominantMonthDate;
return Text('${month.monthNameLocalized()} ${month.year}');
},
),
IconButton(onPressed: kalenderController.animateToPreviousPage, icon: const Icon(Icons.chevron_left)),
IconButton(onPressed: kalenderController.animateToNextPage, icon: const Icon(Icons.chevron_right)),
ListenableBuilder(
listenable: kalenderController,
builder: (context, child) => DropdownButton<ViewConfiguration>(
value: kalenderController.viewConfiguration,
items: [for (final c in viewConfigurations) DropdownMenuItem(value: c, child: Text(c.name))],
onChanged: (value) => kalenderController.viewConfiguration = value!,
),
),
],
),
Expanded(
child: KalenderView(
eventsController: eventsController,
kalenderController: kalenderController,
),
),
],
);
}
}
Setting kalenderController.viewConfiguration is all a view change takes. What carries over,
such as the date and scroll position, is set on the configuration itself, see
Views.
The basic example has a fuller version of this toolbar.
Callbacks
Pass a KalenderCallbacks to KalenderView to react to user interactions.
KalenderCallbacks(
// --- Event interactions ---
// Called when an event tile is tapped.
onEventTapped: (event) {},
// With tap position and the tile's RenderBox.
onEventTappedWithDetail: (event, detail) {},
// Called when an event is secondary tapped (right-clicked).
onEventSecondaryTapped: (event) {},
onEventSecondaryTappedWithDetail: (event, detail) {},
// Called before the calendar creates a new event from a gesture.
// Return your concrete Event subclass here.
onEventCreate: (event) {
return Event(start: event.start,
end: event.end, title: 'New Event');
},
// onEventCreateWithDetail: (event, detail) {...} also receives the gesture
// detail, and is used instead of onEventCreate when set.
// Called after a new event has been committed. Add it to your controller here.
onEventCreated: (event) => eventsController.addEvent(event),
// Called just before a rescheduled / resized event is applied.
onEventChange: (event) {},
// Called after a rescheduled / resized event is applied.
onEventChanged: (original, updated) {
eventsController.updateEvent(event: original, updatedEvent: updated);
},
// --- Calendar interactions ---
// Called when the visible page changes.
onPageChanged: (visibleDateTimeRange) {},
// Called when the vertical scroll position of a multi-day view changes.
// 'visibleTimeOfDay' is the time aligned with the top of the viewport.
onScrollPositionChanged: (visibleTimeOfDay) {},
// Called when the user taps an empty area (day / week body, month cell,
// empty schedule day).
onTapped: (date) {},
onTappedWithDetail: (detail) {
// detail.dateTime or detail.dateTimeRange, plus renderBox & localOffset.
},
// Called when the user secondary taps (right-clicks) an empty area.
onSecondaryTapped: (date) {},
onSecondaryTappedWithDetail: (detail) {},
// Called when the user long-presses an empty area.
onLongPressed: (date) {},
onLongPressedWithDetail: (detail) {},
// Called when the user secondary long-presses an empty area.
onSecondaryLongPressed: (date) {},
onSecondaryLongPressedWithDetail: (detail) {},
// Taps, secondary taps and long presses on a date label (day number, day
// name, schedule date) and on a week number. Each listens only for what is set.
dateLabel: GestureCallbacks(onTap: (detail) {}),
weekNumber: GestureCallbacks(onTap: (detail) {}),
// --- Drag-and-drop acceptance ---
// Day / week vertical drag target. Return false to reject the drop.
onWillAcceptWithDetailsVertical: (details, controller, configuration) => true,
// Month / header horizontal drag target.
onWillAcceptWithDetailsHorizontal: (details, controller, configuration) => true,
)
Classes
- ContinuousScheduleViewController Controllers and callbacks
- The ScheduleViewController of ScheduleViewConfiguration.continuous, one list over the display range.
- DayDetail Controllers and callbacks
- The detail for when the calendar is tapped.
-
GestureCallbacks<
T extends TapDetail> Controllers and callbacks - The gestures reported for one part of the calendar, such as KalenderCallbacks.dateLabel.
- KalenderCallbacks Controllers and callbacks
- The callbacks used by the KalenderView.
- KalenderController Controllers and callbacks
- Holds the ViewConfiguration and Location of a calendar and the ViewController a KalenderView shows.
- KalenderScope Controllers and callbacks
- Reads the state of the KalenderView a widget is built inside.
- MonthViewController Controllers and callbacks
-
The controller of a month view. It opens on the month of the date of
initial. - MultiDayDetail Controllers and callbacks
- The detail for when a multi-day range is tapped.
- MultiDayViewController Controllers and callbacks
-
The controller of a multi-day view. It opens on the date, time of day and zoom of
initial. - PaginatedScheduleViewController Controllers and callbacks
- The ScheduleViewController of ScheduleViewConfiguration.paginated, one page per month.
- ScheduleViewController Controllers and callbacks
-
The controller of a schedule view. It opens on the date of
initial. - TapDetail Controllers and callbacks
- The detail of a gesture on the calendar, a DayDetail or a MultiDayDetail depending on the calendar view.
- ViewController Controllers and callbacks
- A controller for calendar views.
Typedefs
- OnEventChange = void Function(KalenderEvent event) Controllers and callbacks
- The callback for when an event is about to be changed.
- OnEventChanged = void Function(KalenderEvent event, KalenderEvent updatedEvent) Controllers and callbacks
- The callback for when an event is changed.
- OnEventCreate = KalenderEvent? Function(KalenderEvent event) Controllers and callbacks
- The call back for creating a new event.
- OnEventCreated = void Function(KalenderEvent event) Controllers and callbacks
- The callback for a new event has been created.
- OnEventCreateWithDetail = KalenderEvent? Function(KalenderEvent event, TapDetail detail) Controllers and callbacks
- The call back for creating a new event with details.
- OnEventTapped = void Function(KalenderEvent event) Controllers and callbacks
- The callback for when an event is tapped.
- OnEventTappedWithDetail = void Function(KalenderEvent event, TapDetail detail) Controllers and callbacks
- The callback for when an event is tapped.
-
OnGesture<
T extends TapDetail> = void Function(T detail) Controllers and callbacks - A callback for a gesture on one part of the calendar.
- OnLongPressed = void Function(DateTime date) Controllers and callbacks
- The callback for when a user long presses on an empty space in the calendar.
- OnLongPressedWithDetail = void Function(TapDetail detail) Controllers and callbacks
- The callback for when a user long presses on an empty space in the calendar with details.
- OnPageChanged = void Function(KalenderDateTimeRange dateTimeRange) Controllers and callbacks
- The callback for when a calendar page is changed.
- OnScrollPositionChanged = void Function(KalenderTime visibleTimeOfDay) Controllers and callbacks
- The callback for when the vertical scroll position of a multi-day view changes.
- OnTapped = void Function(DateTime date) Controllers and callbacks
- The callback for when a user taps on an empty space in the calendar.
- OnTappedWithDetail = void Function(TapDetail detail) Controllers and callbacks
- The callback for when a user taps on an empty space in the calendar with details.